﻿using System;
using System.Globalization;
using System.Security.Authentication;
using System.Web;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
using Kaesoft.Hospedaje.Entities;
using Kaesoft.Hospedaje.Data;
using System.Linq;
using System.Security.Principal;
using System.ServiceModel;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using Kaesoft.Hospedaje.Business;
using System.Data.Objects.SqlClient;


namespace Kaesoft.Hospedaje.Business
{
    public partial class ReservacionBusiness
    {
        #region Variables
        #endregion

        public bool ActualizaPerfilF(string perfilNombre, Guid perfilId)
        {
            Guid transactionToken = Guid.Empty;

            try
            {
                transactionToken = TransactionHelper.CreateTransaction();
                Perfil perfilModificado = null;
                using (var ctx = new ReservacionesEntities())
                {


                    perfilModificado = (from dato in ctx.Perfils where dato.idPerfil == perfilId select dato).FirstOrDefault();
                    perfilModificado.nombre = perfilNombre;
                    EntidadesUtil.SetCamposAuditoria(ctx, perfilModificado, ServerCache.ObtenerDatosAuditoria(), false, false);
                    ctx.Perfils.ApplyChanges(perfilModificado);
                    ctx.SaveChanges();
                    TransactionHelper.CommitTransaction(ref transactionToken);
                }
            }
            catch (Exception er)
            {

                if (ExceptionPolicy.HandleException(er, Constants.ExceptionPolicyDataAccess)) { throw; };
            }
            finally
            {

                if (Guid.Empty != transactionToken)
                {
                    TransactionHelper.RollbackTransaction(transactionToken);
                }
            }
            return true;
        }

        public bool GuardarPerfilOpcion(string perfilNombre, Guid perfilId, List<PerfilOpcion> poAgregar)
        {
            Guid transactionToken = Guid.Empty;

            try
            {
                transactionToken = TransactionHelper.CreateTransaction();
                Perfil perfilModificado = null;
                using (var ctx = new ReservacionesEntities())
                {
                    perfilModificado = (from dato in ctx.Perfils where dato.idPerfil == perfilId select dato).FirstOrDefault();
                    perfilModificado.nombre = perfilNombre;
                    EntidadesUtil.SetCamposAuditoria(ctx, perfilModificado, ServerCache.ObtenerDatosAuditoria(), false, false);
                    ctx.Perfils.ApplyChanges(perfilModificado);
                    ctx.SaveChanges();
                    poAgregar.ForEach(a =>
                    {
                        EntidadesUtil.SetCamposAuditoria(ctx, a, ServerCache.ObtenerDatosAuditoria(), false, true);
                        ctx.PerfilOpcions.ApplyChanges(a);
                        ctx.SaveChanges();
                    });

                    TransactionHelper.CommitTransaction(ref transactionToken);
                }
            }
            catch (Exception er)
            {

                if (ExceptionPolicy.HandleException(er, Constants.ExceptionPolicyDataAccess)) { throw; };
            }
            finally
            {

                if (Guid.Empty != transactionToken)
                {
                    TransactionHelper.RollbackTransaction(transactionToken);
                }
            }
            return true;
        }

        public Usuario ValidarCredenciales(string login, string pass)
        {
            Usuario usuarioAutenticado = null;

            try
            {
                using (ReservacionesEntities context = new ReservacionesEntities())
                {

                    var usuario = (from usuarios in context.Usuarios
                                   where !usuarios.borrado && usuarios.estado
                                   && (usuarios.usuario1.Trim() == login.Trim() && usuarios.clave == pass)
                                   select new
                                   {
                                       usuario = usuarios,
                                       usuarioPerfil = from usuarioPerfiles in context.UsuarioPerfils
                                                       where !usuarioPerfiles.borrado
                                                             && usuarioPerfiles.idUsuario == usuarios.idUsuario
                                                       select new
                                                       {
                                                           usuarioPerfiles,
                                                           perfil = from perfiles in context.Perfils
                                                                    where !perfiles.borrado
                                                                    && perfiles.idPerfil == usuarioPerfiles.idPerfil
                                                                    select new
                                                                    {
                                                                        perfiles,
                                                                        perfilOpcion = from perfilOpciones in context.PerfilOpcions
                                                                                       where !perfilOpciones.borrado
                                                                                       && perfilOpciones.idPerfil == perfiles.idPerfil
                                                                                       select new
                                                                                       {
                                                                                           perfilOpciones,
                                                                                           opcion = from opciones in context.Opcions
                                                                                                    where !opciones.borrado
                                                                                                    && opciones.idOpcion == perfilOpciones.idOpcion
                                                                                                    select new
                                                                                                    {
                                                                                                        opciones,
                                                                                                        operacion = from operaciones in context.PerfilOpcionOperacions where !operaciones.borrado && perfilOpciones.idPerfil == operaciones.idPerfil && perfilOpciones.idOpcion == operaciones.idOpcion select operaciones
                                                                                                    }
                                                                                       }
                                                                    }
                                                       }

                                   }).SingleOrDefault();

                    if (usuario != null)
                    {
                        usuarioAutenticado = usuario.usuario;
                        GrabarCache(usuarioAutenticado, HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]);
                    }
                }
            }
            catch (Exception ex)
            {
                if (ExceptionPolicy.HandleException(ex, Constants.ExceptionPolicyDataAccess)) { throw; }
            }

            return usuarioAutenticado;
        }

        /// <summary>
        /// obtener una lista de perfiles 
        /// </summary>
        /// <returns></returns>
        public List<Perfil> ObtenerPerfiles()
        {
            List<Perfil> lista = null;
            try
            {
                using (ReservacionesEntities contexto = new ReservacionesEntities())
                {
                    lista = (from perfiles in contexto.Perfils where !perfiles.borrado select perfiles).ToList();

                }

            }
            catch (Exception ex)
            {

                if (ExceptionPolicy.HandleException(ex, Constants.ExceptionPolicyDataAccess)) { throw; };
            }
            return lista;

        }

        #region ObtenerUsuariosPorCriterios
        /// <summary>
        /// Obtiene un listado de usuarios en función de los criterios de busqueda
        /// </summary>
        /// <param name="tipoConsulta">Tipo de búsqueda</param>
        /// <param name="criterio">Criterio de búsqueda</param>
        /// <returns>Lista de Usuarios</returns>
        public PaginatedList<Usuario> ObtenerUsuariosPorCriterios(int tipoConsulta, string criterio, int indice)
        {
            int criterioNumerico = tipoConsulta == (int)TipoConsultaUsuario.Codigo ? Convert.ToInt32(criterio) : 0;
            int total = 0;
            List<Usuario> lista = new List<Usuario>();

            try
            {
                using (ReservacionesEntities contexto = new ReservacionesEntities())
                {
                    total = (from usuario in contexto.Usuarios
                             where (!usuario.borrado) && ((usuario.nombre.Contains(criterio) && tipoConsulta == (int)TipoConsultaUsuario.Nombre)
                             || (usuario.usuario1.Contains(criterio) && tipoConsulta == (int)TipoConsultaUsuario.Usuario)
                             || (usuario.identificacion.Equals(criterio) && tipoConsulta == (int)TipoConsultaUsuario.Identificacion))
                             select usuario
                        ).Count();

                    lista = (from usuario in contexto.Usuarios
                             where (!usuario.borrado) && ((usuario.nombre.Contains(criterio) && tipoConsulta == (int)TipoConsultaUsuario.Nombre)
                             || (usuario.usuario1.Contains(criterio) && tipoConsulta == (int)TipoConsultaUsuario.Usuario)
                             || (usuario.identificacion.Equals(criterio) && tipoConsulta == (int)TipoConsultaUsuario.Identificacion))
                             select usuario
                        ).ToList().OrderBy(a => a.nombre).Skip(EntidadesUtil.PageSize * (indice)).Take(EntidadesUtil.PageSize).ToList(); ;

                    lista.ForEach(a =>
                    {
                        var perfilActual = contexto.UsuarioPerfils.Include("Perfil").Where(b => b.idUsuario == a.idUsuario).FirstOrDefault();
                        a.idPerfil = perfilActual.idPerfil;
                        a.PerfilNombre = perfilActual.Perfil.nombre;
                    });
                }
            }
            catch (Exception ex)
            {

                if (ExceptionPolicy.HandleException(ex, Constants.ExceptionPolicyDataAccess)) { throw; };
            }

            return new PaginatedList<Usuario>(lista, total);
        }
        #endregion

        #region GrabarUsuarios
        /// <summary>
        /// graba los usuarios nuevos
        /// </summary>
        /// <returns></returns>
        public void GrabarUsuarios(List<Usuario> usuarios)
        {
            Guid transactionToken = Guid.Empty;

            try
            {
                transactionToken = TransactionHelper.CreateTransaction();

                using (ReservacionesEntities ctx = new ReservacionesEntities())
                {
                    foreach (var usuario in usuarios)
                    {
                        switch (usuario.ChangeTracker.State)
                        {
                            case ObjectState.Added:
                                usuario.idUsuario = Guid.NewGuid();
                                usuario.cabiarClave = true;
                                usuario.UsuarioPerfils.Add(new UsuarioPerfil() { idUsuarioPerfil = Guid.NewGuid(), idPerfil = usuario.idPerfil });
                                EntidadesUtil.SetCamposAuditoria(ctx, usuario.UsuarioPerfils.First(), ServerCache.ObtenerDatosAuditoria(), false, false);
                                break;
                            case ObjectState.Modified:
                                usuario.UsuarioPerfils.First().idPerfil = usuario.idPerfil;
                                break;
                        }

                        EntidadesUtil.SetCamposAuditoria(ctx, usuario, ServerCache.ObtenerDatosAuditoria(), false, false);
                        ctx.Usuarios.ApplyChanges(usuario);
                    }
                    ctx.SaveChanges();

                    TransactionHelper.CommitTransaction(ref transactionToken);
                }
            }
            catch (Exception ex)
            {
                if (ExceptionPolicy.HandleException(ex, Constants.ExceptionPolicyDataAccess)) { throw; };
            }
            finally
            {
                // si existe aun la transaccion, rollback
                if (Guid.Empty != transactionToken)
                {
                    TransactionHelper.RollbackTransaction(transactionToken);
                }
            }
        }
        #endregion

        #region Metodos Privados
        /// <summary>
        /// Registrar el usuario autenticado en el log
        /// </summary>
        private void EscribirLogAutenticacion()
        {
            //escribir en el log quien está accesando al servicio
            string threadAutenticado = "NA";
            string tipoIdentidadThread = "NA";
            string identidadThread = "NA";
            string primarioAutenticado = "NA";
            string tipoIdentidadPrimario = "NA";
            string identidadPrimario = "NA";


            try { threadAutenticado = System.Threading.Thread.CurrentPrincipal.Identity.IsAuthenticated.ToString(); }
            catch (Exception ex) { Log.WriteTraceEntry(ex.ToString()); }

            try { tipoIdentidadThread = System.Threading.Thread.CurrentPrincipal.Identity.AuthenticationType; }
            catch (Exception ex) { Log.WriteTraceEntry(ex.ToString()); }

            try { identidadThread = System.Threading.Thread.CurrentPrincipal.Identity.Name; }
            catch (Exception ex) { Log.WriteTraceEntry(ex.ToString()); }

            try { primarioAutenticado = HttpContext.Current.User.Identity.IsAuthenticated.ToString(); }
            catch (Exception ex) { Log.WriteTraceEntry(ex.ToString()); }

            try { tipoIdentidadPrimario = HttpContext.Current.User.Identity.AuthenticationType; }
            catch (Exception ex) { Log.WriteTraceEntry(ex.ToString()); }

            try { identidadPrimario = HttpContext.Current.User.Identity.Name; }
            catch (Exception ex) { Log.WriteTraceEntry(ex.ToString()); }

            System.Text.StringBuilder builder = new System.Text.StringBuilder();
            builder.AppendFormat("Login Exitoso.\r\n ThreadAutenticado:{0}. Tipo:{1}. Nombre:{2}.\r\n", threadAutenticado, tipoIdentidadThread, identidadThread);
            builder.AppendFormat("Identidad Primaria. Anónima:{0}. Tipo:{1}. Nombre:{2}.\r\n", primarioAutenticado, tipoIdentidadPrimario, identidadPrimario);

            Log.WriteTraceEntry(builder.ToString());
        }

        /// <summary>
        /// Grabar los datos de usuario en cache
        /// </summary>
        /// <param name="usuario">Usuario autenticado</param>
        private void GrabarCache(Usuario usuario, string ip)
        {
            AuditData auditData = new AuditData(usuario.usuario1, Constants.Programa, ip);
            ServerCache.GrabarDatosAuditoria(auditData);
            ServerCache.GrabarUsuarioAutenticado(usuario);
        }
        #endregion

        #region Validar Usuarios
        public Dictionary<string, int> ValidaUsuario(Usuario usuarioValidar)
        {
            Dictionary<string, int> verificador = new Dictionary<string, int>() { { "UserName", 0 }, { "UserKeys", 0 } };

            using (var ctx = new ReservacionesEntities())
            {
                if (!string.IsNullOrEmpty(usuarioValidar.usuario1))
                {
                    var usuarios = (from data in ctx.Usuarios
                                    where data.usuario1 == usuarioValidar.usuario1
                                    select data).ToList();

                    if (usuarioValidar.ChangeTracker.State == ObjectState.Added)
                        verificador["UserName"] = usuarios != null ? usuarios.Count : 0;

                    if (usuarioValidar.ChangeTracker.State == ObjectState.Modified && usuarios.Count > 0)
                    {
                        int usuariosId = (from data in usuarios
                                          where data.idUsuario == usuarioValidar.idUsuario
                                          select data).ToList().Count;
                        if (usuariosId == 0)
                            verificador["UserName"] = 1;
                        else
                            verificador["UserName"] = 0;
                    }
                }
            }
            return verificador;
        }
        #endregion

        #region Metodos Publicos
        public List<Perfil> ListarArbolPerfiles()
        {
            List<Perfil> perfiles = null;
            try
            {
                using (var ctx = new ReservacionesEntities())
                {
                    perfiles = (from perfilDatos in ctx.Perfils.Include("PerfilOpcions.PerfilOpcionOperacions")
                                where !perfilDatos.borrado
                                orderby perfilDatos.nombre
                                select perfilDatos).ToList();
                }
            }
            catch (Exception ex)
            {
                if (ExceptionPolicy.HandleException(ex, Constants.ExceptionPolicyDataAccess)) { throw; };
            }
            return perfiles;
        }
        public List<Opcion> ListarArbolOpciones()
        {
            List<Opcion> Opciones = null;
            using (var ctx = new ReservacionesEntities())
            {
                Opciones = (from opcionesDatos in ctx.Opcions
                            where opcionesDatos.idPadre == null
                            select opcionesDatos).ToList();
            }
            return Opciones;
        }
        public List<Opcion> ListarArbolOpcionesPorId(Guid idOpcion)
        {
            List<Opcion> Opciones = null;
            using (var ctx = new ReservacionesEntities())
            {
                Opciones = (from opcionesDatos in ctx.Opcions
                            where opcionesDatos.idPadre == idOpcion
                            select opcionesDatos).ToList();
            }
            return Opciones;
        }
        public List<Operacion> ListarOperaciones()
        {
            List<Operacion> operaciones = null;
            try
            {
                using (var ctx = new ReservacionesEntities())
                {
                    operaciones = (from operacionDatos in ctx.Operacions
                                   where !operacionDatos.borrado
                                   orderby operacionDatos.nombre
                                   select operacionDatos).ToList();
                }
            }
            catch (Exception ex)
            {
                if (ExceptionPolicy.HandleException(ex, Constants.ExceptionPolicyDataAccess)) { throw; };
            }
            return operaciones;
        }
        public Perfil ObtenerPerfilPorId(Guid idPerfil)
        {
            Perfil perfilResultado = null;
            try
            {
                using (var ctx = new ReservacionesEntities())
                {
                    bool asignado;
                    var resultado = (from perfilDatos in ctx.Perfils
                                     where !perfilDatos.borrado &&
                                     perfilDatos.idPerfil == idPerfil
                                     select new
                                     {
                                         nombre = perfilDatos.nombre,
                                         Comparacion = (from consulta in ctx.PerfilOpcions.Include("Opcion")
                                                        where consulta.idPerfil == idPerfil
                                                        select consulta),

                                         POpcion = (from consulta in ctx.PerfilOpcions.Include("Opcion")
                                                    where consulta.idPerfil == idPerfil && !consulta.borrado
                                                    select consulta),
                                         Opciones = (from consulta in ctx.PerfilOpcions.Include("Opcion")
                                                     where consulta.idPerfil == idPerfil && !consulta.borrado
                                                     select consulta).Select(a => a.Opcion),
                                         Usuarios = (from usu in ctx.Perfils.Include("UsuarioPerfils")
                                                     where !usu.borrado &&
                                                     usu.idPerfil == idPerfil
                                                     select usu).Select(a => a.UsuarioPerfils).FirstOrDefault()
                                     }).First();
                    if (resultado.Usuarios.Count > 0)
                        asignado = true;
                    else
                        asignado = false;

                    perfilResultado = new Perfil() { nombre = resultado.nombre, Opciones = resultado.Opciones.ToList(), Asignado = asignado, PerfilOpcions = new TrackableCollection<PerfilOpcion>(resultado.POpcion), TodosLosRegistros = new List<PerfilOpcion>(resultado.Comparacion) };
                }
            }
            catch (Exception ex)
            {
                if (ExceptionPolicy.HandleException(ex, Constants.ExceptionPolicyDataAccess)) { throw; };
            }
            return perfilResultado;
        }

        public Perfil ObtenerPerfilPorNombre(string nombrePerfil)
        {
            Perfil perfilResultado = null;
            try
            {
                using (var ctx = new ReservacionesEntities())
                {
                    perfilResultado = (from perfilDatos in ctx.Perfils
                                       where !perfilDatos.borrado &&
                                       perfilDatos.nombre == nombrePerfil
                                       select perfilDatos).FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                if (ExceptionPolicy.HandleException(ex, Constants.ExceptionPolicyDataAccess)) { throw; };
            }
            return perfilResultado;
        }

        public List<Operacion> ObtenerOperacionPorPerfilYOpcion(Guid idPerfil, Guid idOpcion)
        {
            List<Operacion> resultado = null;
            using (var ctx = new ReservacionesEntities())
            {
                resultado = (from OperacionDatos in ctx.Operacions
                             join perfilOpcionOperacionDatos in ctx.PerfilOpcionOperacions
                             on OperacionDatos.idOperacion equals perfilOpcionOperacionDatos.idOperacion
                             where perfilOpcionOperacionDatos.idPerfil == idPerfil &&
                             perfilOpcionOperacionDatos.idOpcion == idOpcion
                             select OperacionDatos).ToList();
            }
            return resultado;
        }
        #endregion

        #region Metodos Publicos
        public Perfil InsertarNuevoPerfil(Perfil nuevoPerfil)
        {
            Guid transactionToken = Guid.Empty;
            try
            {
                transactionToken = TransactionHelper.CreateTransaction();
                using (var ctx = new ReservacionesEntities())
                {
                    EntidadesUtil.SetCamposAuditoria(ctx, nuevoPerfil, ServerCache.ObtenerDatosAuditoria(), true, true);
                    ctx.Perfils.ApplyChanges(nuevoPerfil);
                    ctx.SaveChanges();
                    TransactionHelper.CommitTransaction(ref transactionToken);
                }
            }
            catch (Exception ex)
            {
                if (ExceptionPolicy.HandleException(ex, Constants.ExceptionPolicyDataAccess)) { throw; };
            }
            finally
            {
                // si existe aun la transaccion, rollback
                if (Guid.Empty != transactionToken)
                {
                    TransactionHelper.RollbackTransaction(transactionToken);
                }
            }
            return nuevoPerfil;
        }
        #endregion

        #region Metodos publicos
        public bool ActualizaPerfil(string perfilNombre, Guid perfilId, List<PerfilOpcion> poEliminar, List<PerfilOpcion> poAgregar, List<PerfilOpcionOperacion> pooEliminar, List<PerfilOpcionOperacion> pooAgregar)
        {
            StringBuilder sqlSelect = new StringBuilder();

            pooAgregar.ForEach(a =>
            {
                sqlSelect.AppendLine("select * from PerfilOpcionOperacion where idOpcion = '" + a.idOpcion.ToString() + "'");
                sqlSelect.AppendLine("and idPerfil='" + a.idPerfil.ToString() + "'");
                sqlSelect.AppendLine("and idOperacion ='" + a.idOperacion.ToString() + "'");
            });

            Guid transactionToken = Guid.Empty;
            Perfil perfilModificado = null;
            try
            {
                transactionToken = TransactionHelper.CreateTransaction();
                using (var ctx = new ReservacionesEntities())
                {
                    perfilModificado = (from dato in ctx.Perfils where dato.idPerfil == perfilId select dato).FirstOrDefault();
                    perfilModificado.nombre = perfilNombre;
                    EntidadesUtil.SetCamposAuditoria(ctx, perfilModificado, ServerCache.ObtenerDatosAuditoria(), false, false);
                    ctx.Perfils.ApplyChanges(perfilModificado);
                    ctx.SaveChanges();
                    pooEliminar.ForEach(c =>
                    {
                        var consulta = (from dato in ctx.PerfilOpcionOperacions where dato.idOpcion == c.idOpcion && dato.idOperacion == c.idOperacion && dato.idPerfil == c.idPerfil select dato).FirstOrDefault();
                        if (consulta != null)
                        {
                            ctx.PerfilOpcionOperacions.DeleteObject(consulta);
                            ctx.SaveChanges();
                        }
                    });

                    poEliminar.ForEach(b =>
                    {
                        var consulta = (from dato in ctx.PerfilOpcions.Include("PerfilOpcionOperacions") where dato.idOpcion == b.idOpcion && dato.idPerfil == b.idPerfil select dato).FirstOrDefault();
                        if (consulta != null)
                        {
                            ctx.PerfilOpcions.DeleteObject(consulta);
                            ctx.SaveChanges();
                        }
                    });

                    poAgregar.ForEach(a =>
                    {
                        var existe = ctx.PerfilOpcions.Where(b => b.idOpcion == a.idOpcion && b.idPerfil == a.idPerfil).FirstOrDefault();
                        if (existe == null)
                        {
                            var consulta = new PerfilOpcion()
                            {
                                idOpcion = a.idOpcion,
                                idPerfil = a.idPerfil
                            };
                            EntidadesUtil.SetCamposAuditoria(ctx, consulta, ServerCache.ObtenerDatosAuditoria(), false, false);
                            ctx.PerfilOpcions.AddObject(consulta);
                            ctx.SaveChanges();
                        }
                    });

                    pooAgregar.ForEach(d =>
                    {
                        var existe = ctx.PerfilOpcionOperacions.Where(a => a.idOpcion == d.idOpcion && a.idOperacion == d.idOperacion && a.idPerfil == d.idPerfil).FirstOrDefault();
                        if (existe == null)
                        {
                            var consulta = new PerfilOpcionOperacion()
                            {
                                idOpcion = d.idOpcion,
                                idOperacion = d.idOperacion,
                                idPerfil = d.idPerfil,
                                operacion = d.operacion
                            };
                            EntidadesUtil.SetCamposAuditoria(ctx, consulta, ServerCache.ObtenerDatosAuditoria(), false, false);
                            ctx.PerfilOpcionOperacions.AddObject(consulta);
                            ctx.SaveChanges();
                        }
                    });
                    TransactionHelper.CommitTransaction(ref transactionToken);
                }
            }
            catch (Exception ex)
            {
                if (ExceptionPolicy.HandleException(ex, Constants.ExceptionPolicyDataAccess)) { throw; };
            }
            finally
            {
                // si existe aun la transaccion, rollback
                if (Guid.Empty != transactionToken)
                {
                    TransactionHelper.RollbackTransaction(transactionToken);
                }
            }
            return true;
        }
        #endregion

        #region Eliminar infomacion de Perfiles
        public bool EliminaPerfiles(List<Perfil> perfiles)
        {
            bool result;
            Guid transactionToken = Guid.Empty;
            try
            {
                using (var ctx = new ReservacionesEntities())
                {
                    perfiles.ForEach(a =>
                                         {
                                             var consulta = (from dato in ctx.Perfils.Include("PerfilOpcions.PerfilOpcionOperacions") where dato.idPerfil == a.idPerfil select dato).FirstOrDefault();
                                             consulta.borrado = true;
                                             if (consulta != null)
                                             {
                                                 EntidadesUtil.SetCamposAuditoria(ctx, consulta, ServerCache.ObtenerDatosAuditoria(), false, false);
                                                 ctx.Perfils.ApplyChanges(consulta);
                                                 ctx.SaveChanges();
                                             }
                                         });
                    result = true;

                }
            }
            catch (Exception ex)
            {
                if (ExceptionPolicy.HandleException(ex, Constants.ExceptionPolicyDataAccess)) { throw; };
                result = false;
            }
            finally
            {
                // si existe aun la transaccion, rollback
                if (Guid.Empty != transactionToken)
                {
                    TransactionHelper.RollbackTransaction(transactionToken);
                }
            }
            return result;
        }


        public void RestaurarClave(Guid idUsuarioResetear)
        {
            Guid transactionToken = Guid.Empty;
            try
            {
                transactionToken = TransactionHelper.CreateTransaction();
                using (var ctx = new ReservacionesEntities())
                {
                    Usuario usuarioReset = (from data in ctx.Usuarios where data.idUsuario == idUsuarioResetear select data).FirstOrDefault();
                    usuarioReset.clave = "abc";
                    usuarioReset.cabiarClave = true;
                    EntidadesUtil.SetCamposAuditoria(ctx, usuarioReset, ServerCache.ObtenerDatosAuditoria(), false, false, "");
                    ctx.Usuarios.ApplyChanges(usuarioReset);
                    ctx.SaveChanges();
                    TransactionHelper.CommitTransaction(ref transactionToken);
                }
            }
            catch (Exception ex)
            {
                if (ExceptionPolicy.HandleException(ex, Constants.ExceptionPolicyDataAccess)) { throw; };
            }
            finally
            {
                // si existe aun la transaccion, rollback
                if (Guid.Empty != transactionToken)
                {
                    TransactionHelper.RollbackTransaction(transactionToken);
                }
            }
        }

        public bool ValidarUsuario(string usuario, string clave)
        {
            bool resultado = false;

            try
            {
                using (ReservacionesEntities context = new ReservacionesEntities())
                {

                    resultado = (from usuarios in context.Usuarios
                                 where !usuarios.borrado && usuarios.estado
                                        && (usuarios.usuario1.Trim() == usuario.Trim() && usuarios.clave == clave)
                                 select usuario).Any();
                }
            }
            catch (Exception ex)
            {
                if (ExceptionPolicy.HandleException(ex, Constants.ExceptionPolicyDataAccess)) { throw; };
            }

            return resultado;
        }
        #endregion

        # region PerfilOpcionOperacion

        public List<Operacion> ObtenerDatosOpcionOperacion(Guid idPerfil, Guid idOpcion)
        {
            List<Operacion> result = new List<Operacion>();

            try
            {
                using (var ctx = new ReservacionesEntities())
                {

                    result = (from data in ctx.Operacions.Include("PerfilOpcionOperacion").Include("PerfilOpcionOperacion.PerfilOpcion")
                              join d in ctx.OpcionOperacions
                              on data.idOperacion equals d.idOperacion
                              where d.idOpcion == idOpcion && !data.borrado
                              select data).ToList();

                    var OperacionesExcluidas = (from data in ctx.PerfilOpcionOperacions
                                                where data.idOpcion == idOpcion
                                                && data.idPerfil == idPerfil && !data.borrado
                                                select data).ToList();

                    if (OperacionesExcluidas.Count > 0)
                    {
                        result.ForEach(a =>
                        {
                            if (OperacionesExcluidas.Where(b => b.operacion.Trim() == a.nombre.Trim()).Count() > 0)
                                a.EsSeleccionado = true;
                        });
                    }
                }
            }
            catch (Exception ex)
            {
                if (ExceptionPolicy.HandleException(ex, Constants.ExceptionPolicyDataAccess)) { throw; };
            }

            return result;
        }

        public void GuardaOperacion(PerfilOpcion PropiedadPerfilOpcion)
        {
            Guid transactionToken = Guid.Empty;

            try
            {
                transactionToken = TransactionHelper.CreateTransaction();

                using (ReservacionesEntities ctx = new ReservacionesEntities())
                {
                    EntidadesUtil.SetCamposAuditoria(ctx, PropiedadPerfilOpcion, ServerCache.ObtenerDatosAuditoria(), true, false); ctx.PerfilOpcions.ApplyChanges(PropiedadPerfilOpcion);
                    ctx.SaveChanges();

                    TransactionHelper.CommitTransaction(ref transactionToken);
                }
            }
            catch (Exception ex)
            {
                if (ExceptionPolicy.HandleException(ex, Constants.ExceptionPolicyDataAccess)) { throw; };
            }
            finally
            {
                // si existe aun la transaccion, rollback
                if (Guid.Empty != transactionToken)
                {
                    TransactionHelper.RollbackTransaction(transactionToken);
                }
            }
        }
        #endregion

        #region PerfilOpcion

        public PerfilOpcion ObtenerPerfilOpcion(Guid IdPerfil, Guid IdOpcion)
        {
            PerfilOpcion resultado = new PerfilOpcion();

            try
            {
                using (var ctx = new ReservacionesEntities())
                {
                    resultado = (from data in ctx.PerfilOpcions.Include("PerfilOpcionOperacions.Operacion1")
                                 where data.idPerfil == IdPerfil
                                 && data.idOpcion == IdOpcion
                                 select data).FirstOrDefault();
                }
            }

            catch (Exception ex)
            {
                if (ExceptionPolicy.HandleException(ex, Constants.ExceptionPolicyDataAccess)) { throw; };
            }

            return resultado;
        }
        #endregion
    }
}